﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using KadalaSpree.XCore;
using Zeta.Game.Internals.Actors;
using Zeta.TreeSharp;
using Action = Zeta.TreeSharp.Action;

namespace KadalaSpree.XCore
{
    public partial class X
    {
        public delegate void ActionDelegate(object ret);

        /// <summary>
        /// Always Returns RunStatus.Failure
        /// </summary>
        public static Action ActionFailure(ActionDelegate func)
        {
            func.DynamicInvoke(new object());
            return new Action(ret => RunStatus.Failure);
        }
    }

    internal static class Helpers
    {
        public static readonly Random Random = new Random();

        internal static string GetClassName()
        {
            var name = string.Empty;
            try
            {
                var frame = new StackFrame(2);
                var method = frame.GetMethod();
                name = (method != null && method.DeclaringType!= null) ? method.DeclaringType.Name : string.Empty;
            }
            catch (Exception ex)
            {
                X.Logger.Instance.Log("Exception {0}", ex);
            }
            return name;
        }      
  
        /// <summary>
        /// Check if string is within list of strings (case-insensitive)
        /// </summary> 
        public static Func<IEnumerable<string>, string, bool> Contains = (haystack, needle) =>
        {
            return haystack.Contains(needle, StringComparer.Create(Thread.CurrentThread.CurrentCulture, true));
        };

        public static List<T> GetEnumList<T>()
        {
            return Enum.GetValues(typeof (T)).Cast<T>().ToList();
        }

        public static List<string> GetStringListFromEnum<T>()
        {
            return Enum.GetNames(typeof(T)).ToList();
        }

        public static List<T> GetEnumListFromStrings<T>(List<string> stringList)
        {
            return stringList.Select(s => (T)Enum.Parse(typeof(T), s)).ToList();
        }

    }

    public static class DictionaryExtensions
    {
        /// <summary>
        /// Add the contents of other dictionaries; discards records with duplicate keys.
        /// </summary>
        public static Dictionary<TKey, TVal> Merge<TKey, TVal>(this IDictionary<TKey, TVal> dictA, IDictionary<TKey, TVal>[] dicts)
        {
            var output = new Dictionary<TKey, TVal>(dictA);

            foreach (var dict in dicts)
            {
                foreach (var pair in dict.Where(pair => !dictA.Keys.Contains(pair.Key))) {
                    output.Add(pair.Key, pair.Value);
                }
            }

            return output;
        }
    }

    public static class EnumerableExtensions
    {
        public static void Each<T>(this IEnumerable<T> ie, Action<T, int> action)
        {
            var i = 0;
            foreach (var e in ie) action(e, i++);
        }
    }


}
